
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "get_wifi_ap.h"

static void enable_softap_scanning(void)
{
    system("iwpriv ra0 set SiteSurvey=");
    sleep(2);
}

static void show_wlist(WIFI_AP_INFO_LIST *list)__attribute__((unused));
static void show_wlist(WIFI_AP_INFO_LIST *list)
{
    if (list != NULL)
    {
        int i = 0;
        for (; i < list->len; ++i)
        {
            printf("%-2d\t%-30s\t%-20s\t%-3d\n",
                   list->ap_info[i].channel,
                   list->ap_info[i].ssid,
                   list->ap_info[i].bssid,
                   list->ap_info[i].siganl);
        }
    }
    else
    {
        printf("list is NULL\n");
    }
}

static void str_replace(char *src_str, char c)
{
    int i = 0;
    for (; i < strlen(src_str); ++i)
    {
        if (src_str[i] == c)
        {
            src_str[i] = '\0';
            break;
        }
    }
}

static void parse_softap_res(const char *ap_info, WIFI_AP_INFO *w_ap_info)
{
    int len_channel = 4;
    int len_ssid = 33;
    int len_bssid = 20;
    int len_security = 23;
    int len_signal = 9;
    int offset = 0;

    char channel_str[4] = {0};
    char ssid_str[33] = {0};
    char bssid_str[20] = {0};
    char signal_str[9] = {0};

    memcpy(channel_str, ap_info, len_channel);
    str_replace(channel_str, ' ');
    offset += len_channel;

    memcpy(ssid_str, ap_info + offset, len_ssid);
    str_replace(ssid_str, ' ');
    offset += len_ssid;

    memcpy(bssid_str, ap_info + offset, len_bssid);
    str_replace(bssid_str, ' ');
    offset += len_bssid;
    offset += len_security;

    memcpy(signal_str, ap_info + offset, len_signal);
    str_replace(signal_str, ' ');

    memset(w_ap_info, 0, sizeof(WIFI_AP_INFO));
    w_ap_info->channel = atoi(channel_str);
    w_ap_info->siganl = atoi(signal_str);
    memcpy(w_ap_info->ssid, ssid_str, strlen(ssid_str));
    memcpy(w_ap_info->bssid, bssid_str, strlen(bssid_str));
}

WIFI_AP_INFO_LIST *softap_get_scan_res(void)
{

    FILE *fp;

    enable_softap_scanning();

    if ((fp = popen("iwpriv ra0 get_site_survey", "r")) == NULL)
    {
        return NULL;
    }

    int len = 20;

    WIFI_AP_INFO_LIST *info = (WIFI_AP_INFO_LIST *)malloc(sizeof(WIFI_AP_INFO_LIST));
    if (info == NULL)
    {
        return NULL;
    }

    info->ap_info = (WIFI_AP_INFO *)malloc(sizeof(WIFI_AP_INFO) * (len));
    if (info->ap_info == NULL)
    {
        free(info);
        info = NULL;
        return NULL;
    }

    memset(info->ap_info, 0, sizeof(WIFI_AP_INFO) * (len));
    info->len = 0;

    char buf[256];
    int findFlag = 0;

    while (fgets(buf, 256, fp) != NULL)
    {

        if (!findFlag && strstr(buf, "Ch") != NULL)
        {
            findFlag = 1;
            continue;
        }

        if (findFlag)
        {
          //  printf("[%s:%d] len = %d buf = %s\n", __FILE__, __LINE__, strlen(buf), buf);

            parse_softap_res(buf, &info->ap_info[info->len]);
            info->len++;
        }
    }
    info->len -= 1;

  //  show_wlist(info);

    pclose(fp);

    return info;
}

void softap_apinfo_free(WIFI_AP_INFO_LIST *wlist)
{
    if (wlist == NULL)
    {
        return;
    }

    if (wlist->ap_info != NULL)
    {
        free(wlist->ap_info);
        wlist->ap_info = NULL;
    }

    free(wlist);
    wlist = NULL;
}